package han.chensing.latos.common.level;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.utils.Disposable;
import han.chensing.latos.common.file.annotation.CirnoNotSerialize;
import han.chensing.latos.common.level.content.LevelData;
import han.chensing.latos.common.level.meta.LatosMetaData;
import han.chensing.latos.common.level.sample.SampleData;
import han.chensing.latos.common.level.util.CacheHelper;
import han.chensing.latos.common.level.util.StreamUtil;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;

import java.io.*;

public class LatosProject implements Serializable, Disposable {

    @Serial private static final long serialVersionUID=114514L;

    private SampleData sampleData;
    private LevelData levelData;
    private LatosMetaData latosMetaData;
    @CirnoNotSerialize
    private byte[] musicBytes;
    private String musicFormat;
    private float musicLength;

    @CirnoNotSerialize
    private transient Music music;

    public LatosProject() {
        this.latosMetaData=new LatosMetaData();
        latosMetaData.setName("New Project");
        latosMetaData.setAuthor("You");
        latosMetaData.setDescription("Write here!");
        latosMetaData.setDefaultBpm(120);
        latosMetaData.setBpmDescription("120");
        latosMetaData.setOffset(0);
        this.sampleData=new SampleData();
        this.levelData=new LevelData();
    }

    public SampleData getSampleData() {
        return sampleData;
    }

    public void setSampleData(SampleData sampleData) {
        this.sampleData = sampleData;
    }

    public LevelData getLevelData() {
        return levelData;
    }

    public void setLevelData(LevelData levelData) {
        this.levelData = levelData;
    }

    public byte[] getMusicBytes() {
        return musicBytes;
    }

    public void setMusicBytes(byte[] musicBytes) {
        this.musicBytes = musicBytes;
    }

    public Music getMusic() {
        return music;
    }

    public String getMusicFormat() {
        return musicFormat;
    }

    public void setMusicFormat(String musicFormat) {
        this.musicFormat = musicFormat;
    }

    public float getMusicLength() {
        return musicLength;
    }

    public LatosMetaData getLatosMetaData() {
        return latosMetaData;
    }

    public void setLatosMetaData(LatosMetaData latosMetaData) {
        this.latosMetaData = latosMetaData;
    }

    public void genMusic() throws IOException {
        File tempFile = CacheHelper.getInstance().createCache(musicFormat);
        FileOutputStream fileOutputStream=new FileOutputStream(tempFile);
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(musicBytes);
        StreamUtil.streamCopy(byteArrayInputStream,fileOutputStream);
        byteArrayInputStream.close();
        fileOutputStream.close();
        music=Gdx.audio.newMusic(Gdx.files.absolute(tempFile.getAbsolutePath()));
        try {
            AudioFile audioFile = AudioFileIO.read(tempFile);
            musicLength =audioFile.getAudioHeader().getTrackLength();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void dispose() {
        if (music!=null)music.dispose();
    }
}
